#ifndef PERSONNAGE_H
#define PERSONNAGE_H
#include "Caracteristiques.h"
#include "Carte.h"
#include "CalculTrajet.h"
#include "CompActuel.h"
#include <stdlib.h>

/* Notes :
 
	Autres :
	Penser à faire la doc de ce module (si,si !)
	Rajouter une fonction qui crée un personnage et lui attribue des caractéristiques (à l'aide de la fonction qui va bien) pourrait servir (creePers ? initNouvPers ?)

*/

struct PersStr
{
  unsigned int ID;
  struct PersStr* personnageSuivant;	/*!<lien vers personnage suivant pour
					la lise chainée */
  struct PersStr* personnagePrecedent;	/*!<lien vers personnage precedent
					pour la lise chainée */
  char* nom; 				/*!<chaine de caractères pour le nom
					du personnage */
  char* espece;				/*!<chaine de caractères pour l'espece
					du personnage */
  Caracteristiques* carac;		/*!<module caractéristiques du
					personnage*/
  CompActuel *compActuel;		/*!<lien vers le type de comportement
					du personnage*/
  int vitesseProd;			/*!<taux d'incrémentation de la
					production effectuée à chaque pas de
					temps*/
  unsigned int x;			/*!<position x du personnage*/
  unsigned int y;			/*!<position y du personnage*/
  unsigned int z;			/*!<position z du personnage*/
  CalculTrajet* trajet;			/*!<trajet à effectuer*/
  int prodAct;				/*!< Entier, état de la production
					actuellement faite par le personnage.
					Si aucun, vaut zéro*/
};

typedef struct PersStr Personnage;

/*======================== Gestion de la mémoire =======================*/

void initPers(Personnage* personnage, const unsigned int posX,const unsigned int posY, const unsigned int posZ);

void creerPersonnage(Personnage** personnage, const unsigned int posX,const unsigned int posY, const unsigned int posZ);

/**
* \brief	Libère la mémoire allouée aux champs du Personnage donné
* \details	Met à NULL tous les Pointeurs, désalloue la mémoire réservée
*		initialement pour les tableaux de char
* \param	personnage	Pointeur vers le personnage à libérer
*/
void liberePers(Personnage *personnage);

void detruirePers(Personnage* personnage);

/*============================= Accesseurs =============================*/

unsigned int getIDPers(const Personnage* personnage);

char* getNom(const Personnage* personnage);

char* getEspece(const Personnage* personnage);

Caracteristiques* getCarac(const Personnage* personnage);

/**
* \brief	Retourne le pointeur sur CompActuel du Personnage donné
* \return	Un pointeur sur CompActuel
* \param	personnage	Pointeur vers un Personnage
*/
CompActuel *getCompActuelPers(const Personnage* personnage);

int getVitProd(const Personnage* personnage);

unsigned int getXPers(const Personnage* personnage);

unsigned int getYPers(const Personnage* personnage);

unsigned int getZPers(const Personnage* personnage);

Personnage* getPersonnageSuivant(Personnage* personnage);

/**
* \brief	Retourne l'état où en est la production actuelle du personnage
* \return	Un entier
* \param	personnage	Pointeur vers un Personnage
*/
int getProdActPers(const Personnage *personnage);

/**
* \brief	Retourne la valeur de vitesse de production du personnage donné
* \param	personnage	Pointeur vers personnage
* \return	Un entier
*/
int getVitesseProdPers(const Personnage *personnage);


/*============================== Mutateurs =============================*/

void setIDPers(Personnage* personnage, const unsigned int ID);

void setNomPers(Personnage* personnage, char* nom);

void setEspecePers(Personnage* personnage, char* espece);

void setCaracPers(Personnage* personnage, Caracteristiques* caracteristiques);

/**
* \brief	Remplace le pointeur sur le comportement en cours d'un
*		Personnage donné par un pointeur passé en paramètre
* \param	pcompAct	Pointeur vers un CompActuel
* \param	nouvComp	Nouveau comportement, pointeur vers
*				Comportement
*/
void setComportActuel(Personnage* personnage, CompActuel* nouvComp);

void setXPers(Personnage* personnage, const unsigned int x);

void setYPers(Personnage* personnage, const unsigned int y);

void setZPers(Personnage* personnage, const unsigned int z);

void setPersonnageSuivant(Personnage* personnage, Personnage* personnageSuivant);

/**
* \brief	Remplace la valeur de production actuelle du personnage donné
*		par une nouvelle valeur passée en paramètre
* \param	personnage	Pointeur vers personnage
* \param	nouvVal		Entier, nouvelle valeur
*/
void setProdActPers(Personnage *personnage, int nouvVal);

/**
* \brief	Remplace la valeur de vitesse de production du personnage donné
*		par une nouvelle valeur passée en paramètre
* \param	personnage	Pointeur vers personnage
* \param	nouvVal		Entier, nouvelle valeur
*/
void setVitesseProdPers(Personnage *personnage, int nouvVal);

/**
* \brief	Remplace le pointeur sur le comportement en cours d'un
*		Personnage donné par un comportement dont on aura fourni le
*		nom en paramètre.
* \param	pcompAct	Pointeur vers un CompActuel
* \param	ptabComp	Tableau des comportements possibles
* \param	nomComp		Nouveau comportement, pointeur vers
*				Comportement
*/
void setCompActuelNomCompPers(Personnage* personnage,TabComp *ptabComp, char *nomComp);

/*========================== Fonctions autres ==========================*/
/*
void deplacementPers(Personnage* personnage, const unsigned int xDepart, const unsigned int yDepart, const unsigned int zDepart, const unsigned int xArrivee, const unsigned int yArrivee, const unsigned int zArrivee);
*/

/**
* \brief	Procédure régissant les changements/applications de
*		comportement du nain passé en paramètre.
* \details	Voici le principe : si le nain se trouve sur une case
*		comportant une "Production", il adoptera le comportement
*		approprié à cette production (récolte->fin de récolte). Sinon,
*		il passera en inactif.
* \param	personnage	Pointeur sur personnage
* \param	pcarte		Pointeur sur carte
* \param	ptabComp	Tableau des comportements possibles
* \param	pstock		Pointeur vers l'entrepôt du clan
*/
void changementComportementPers(Personnage* personnage, Carte *pcarte, TabComp *ptabComp, Entrepot *pstock);

/**
* \brief	Crée et renvoie un personnage, ses champs remplis (à part pour
*		suivant et précédent, ainsi que l'ID, qui seront attribués via
*		Population)
* \details	Attention : à n'utiliser qu'après remplissage de la carte !
* \return	Un pointeur sur personnage
* \param	ptabComp	Tableau des comportements possibles
*/
Personnage *creerCompletPers(TabComp *ptabComp);


/*========================== Fonction de Test ==========================*/
/**
* \brief	Teste les différentes fonctions du module Personnage
* \details	Teste les différentes fonctions du module Personnage en les
*		utilisant avec diverses valeurs plus ou moins probables
*/
void testPers();

#endif

